/**
 * http request widget
 *
 * request options:
 * {
 *   name: api id,
 *   url: request url,
 *   data: request data,
 *   method: request method,
 *   header: request header,
 *   params: params set for uri,
 *   dataType: request data type,
 *   responseType: response type,
 * }
 */
import common from '../unit/common.js'

import pathToRegexp from "path-to-regexp";

import config from "./config";

const MODE_NAME = 'NAME';
// const MODE_URI = 'URI';

// 请求任务
let task = null;

function Http() {
	const {
		baseUrl,
		mode,
		apis,
		interceptor,
		options
	} = config;

	this.baseUrl = baseUrl;
	this.mode = mode || MODE_NAME;
	this.apis = apis || [];
	this.interceptor = interceptor || {
		request: null,
		response: null
	};
	this.options = Object.assign({}, {
			data: {},
			header: {},
			method: "GET",
			dataType: "json",
			responseType: "text",
			success() {},
			fail() {},
			complete() {}
		},
		options
	);
}

// 中断请求
Http.prototype.abort = function() {
	if (task) {
		task.abort();
	}
}

Http.prototype.upload = function(name, params, filePath, key) {
	let options = {
		name: name,
		params: params
	}
	let api = null;

	if (this.mode === MODE_NAME) {
		api = getApi(this.apis, options.name, options.params);

		if (api !== null) {
			delete options.name;
			delete options.params;
			options.url = this.baseUrl + api.uri;
		}
	}

	if (!isFullUrl(options.url)) {
		options.url = this.baseUrl + options.url;
	}

	const self = this;
	return new Promise((resolve, reject) => {
		options.complete = (response) => {
			const statusCode = response.statusCode;

			let newResponse = response;
			if (typeof self.interceptor.response === "function") {
				newResponse = self.interceptor.response(newResponse);
			}

			if (statusCode == 200) {
				let data = newResponse.data
				if (data) {
					if (data.code != 200) {
						let msg = data.message ? data.message : data.msg;
						uni.showToast({
							title: msg,
							icon: 'none',
							duration: 2000
						})

						reject(newResponse)
						return
					}
				} else {
					reject(newResponse)
					return
				}
				resolve(newResponse)
			} else {
				reject(newResponse);
			}
		};

		const newOptions = Object.assign({}, self.options, options);

		if (typeof self.interceptor.request === "function") {
			if (self.interceptor.request(newOptions, api) === false) {
				reject(new Error("Unauthorized request"));
			}
		}

		uni.uploadFile({
			url: newOptions.url,
			filePath: filePath,
			name: key,
			// header: {Content-Type: "multipart/form-data",Accept:'application/json'},
			// headers:{
			// 	"Content-Type": "multipart/form-data",
			// 	// Accept:'application/json',
			// 	// Authorization:k
			// },
			formData: newOptions.data,
			success: function(response) {
				const statusCode = response.statusCode;
				let newResponse = response;

				if (statusCode == 200) {
					let data = JSON.parse(newResponse.data)

					if (data) {
						if (data.code != 200) {
							let msg = data.message ? data.message : data.data;
							uni.showToast({
								title: msg,
								icon: 'none',
								duration: 2000
							})

							reject(newResponse)
							return
						}
					} else {
						// uni.showToast({
						// 	title:'数据格式有误' + JSON.stringify(data),
						// 	icon:'none',
						// 	duration:2000
						// })

						reject(newResponse)
						return
					}
					resolve(data)
				} else {
					reject(newResponse);
				}
			}
		});
	});
}
Http.prototype.request = function(options) {
	let api = null;

	if (this.mode === MODE_NAME) {
		api = getApi(this.apis, options.name, options.params, options.idset);
		if (api !== null) {
			options.url = this.baseUrl + api.uri;
			delete options.name;
			delete options.params;
		}
	}

	if (!isFullUrl(options.url)) {
		options.url = this.baseUrl + options.url;
	}
	// uni.showNavigationBarLoading()
	const self = this;
	return new Promise((resolve, reject) => {
		options.complete = (response) => {
			uni.hideLoading()
			// uni.hideNavigationBarLoading()
			const statusCode = response.statusCode;

			let newResponse = response;
			if (typeof self.interceptor.response === "function") {
				newResponse = self.interceptor.response(newResponse);
			}

			if (statusCode == 200) {
				let data = newResponse.data
				if (data) {
					if (data.code == 401) {
						// common.setBackUrl()
						if (!api.hide) {
							let msg = '权限已过期，请重新登录';
							uni.showToast({
								title: msg,
								icon: 'none',
								duration: 2000
							})
						}

						reject(newResponse)
						return
					}
					if (data.code != 200) {
						if (!api.hide) {
							let msg = data.message ? data.message : data.msg;
							uni.showToast({
								title: msg,
								icon: 'none',
								duration: 2000
							})
						}

						reject(newResponse)
						return
					}
				} else {
					// uni.showToast({
					// 	title:'数据格式有误' + JSON.stringify(data),
					// 	icon:'none',
					// 	duration:2000
					// })

					reject(newResponse)
					return
				}
				resolve(newResponse)
			} else {
				reject(newResponse)
			}
		};

		const newOptions = Object.assign({}, self.options, options);

		if (typeof self.interceptor.request === "function") {
			if (self.interceptor.request(newOptions, api) === false) {
				reject(new Error("Unauthorized request"));
			}
		}

		task = uni.request(newOptions);
	});
};

['head', 'options', 'delete'].forEach((method) => {
	Http.prototype[method] = function(name, params, idset) {
		let options = {};

		if (typeof name === "object") {
			options = name;
			return this.request(
				Object.assign(options, {
					method: method.toUpperCase(),
				})
			);
		}

		options.method = method.toUpperCase();
		if (this.mode === MODE_NAME) {
			options.name = name;
			options.params = params;
			options.idset = idset;

			return this.request(options);
		}

		options.url = name;
		if (typeof params === 'object') {
			options = Object.assign({}, options, params);
		}

		return this.request(options);
	};
});

['get', 'post', 'put', 'patch'].forEach((method) => {
	Http.prototype[method] = function(name, data, params, idset) {
		let options = {};

		if (typeof name === "object") {
			options = name;
			return this.request(
				Object.assign(options, {
					method: method.toUpperCase(),
				})
			);
		}

		options.method = method.toUpperCase();
		if (this.mode === MODE_NAME) {
			options.name = name;
			options.data = data;
			options.params = params;
			options.idset = idset;
			return this.request(options);
		}

		options.url = name;
		if (params) options.url += "/" + params;
		options.data = data;
		if (typeof params === 'object') {
			options = Object.assign({}, options, params);
		}

		return this.request(options);
	};
});

Http.prototype.host = function(options) {
	return config.baseUrl
}
/**
 * http widget class
 */
export class HttpWidget {
	install(Vue) {
		Vue.prototype.$http = new Http();
	}
}


export {
	Http,
};

/**
 * Get api object by name. URI will be replaced by data and params
 * @param  {String} name    Api name
 * @param  {Object} params  Request params
 * @return {Object}
 */
function getApi(apis, name, params, idset) {
	if (apis.length <= 0 || !name) {
		return null;
	}
	let api = apis[name];
	let uri = api.uri;

	let keys = [];
	pathToRegexp(uri, keys);

	if (keys.length > 0) {
		keys.forEach(key => {
			if (!params[key.name]) {
				throw new Error(
					`API name: ${name}. You are using dynamic params but ${
                        key.name
                    } not existed in your params`
				);
			}

			uri = uri.replace(`:${key.name}`, params[key.name] || "undefined");
		});
	}
	var url = uri
	if (idset) url += "/" + idset
	if (url.indexOf("?") == -1) {
		url += "?"
	} else {
		url += "&"
	}
	url += "access-token=" + uni.getStorageSync('token')
	
	if(params){
		var plist = []
		for (var i in params){
			plist.push(i+"="+params[i])
		}
		url+="&" + plist.join('&')
	}
	return {
		auth: api.auth,
		uri: url,
		hide: api.hide?api.hide:false
	}
	// return Object.assign(api, {
	//     uri,
	// });
}

function isFullUrl(url) {
	return /(http|https):\/\/([\w.]+\/?)\S*/.test(url);
}
